home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The 640 MEG Shareware Studio 4
/
The 640 Meg Shareware Studio CD-ROM Volume IV (Data Express)(1994).ISO
/
clang
/
pcl4c35.zip
/
AMODEM.C
next >
Wrap
Text File
|
1993-04-25
|
10KB
|
287 lines
/*
** ASCII text file transfer using XON / OFF flow control protocol.
** Transfer ASCII files only. Do not attempt to transfer binary files.
*/
#include <stdio.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include "pcl4c.h"
#include "ascii.h"
#define FALSE 0
#define TRUE !FALSE
#define ONE_SECOND 18
extern int GetChar();
extern int PutChar();
char lastXchar; /* last XON or XOFF sent */
int TxAscii(Port,Filename,Buffer,Length,SyncFlag,CharPace,TermChar,EchoFlag)
int Port; /* COM port [0..3] */
char Filename[]; /* filename buffer */
char Buffer[]; /* data buffer */
int Length; /* size of Buffer */
int SyncFlag; /* synchronize with XON 1st */
int CharPace; /* millisecond delay after sending each character */
int TermChar; /* termination character (0x00 ==> none) */
int EchoFlag; /* do local echo if TRUE */
{int i;
int Code; /* return code */
int Handle; /* file Handle */
char LastChar; /* last character sent */
int TxChars = 0; /* # characters transmitted */
int Count; /* # bytes read from disk */
char Temp[81]; /* temporary buffer */
/* begin */
Handle = open(Filename,O_RDONLY|O_BINARY,S_IREAD);
if(Handle<0)
{strcpy(Temp,"Cannot open ");
strcat(Temp,Filename);
DisplayLine(Temp,NULL,0);
return(FALSE);
}
/* do we wait for XON before starting ? */
if(SyncFlag)
{/* wait for incoming XON */
DisplayLine("ASCII: Waiting for XON",NULL,0);
while(1)
{if(SioBrkKey())
{DisplayLine("Canceled by USER",NULL,0);
return(FALSE);
}
Code = SioGetc(Port,ONE_SECOND);
if(Code==-1) continue;
if(Code<0) return(FALSE);
if((char)Code==XON)
{DisplayLine("ASCII: initial XON received",NULL,0);
/* slight delay */
SioDelay(ONE_SECOND/2);
break;
}
/* received character not XON */
MyCrtWrite((char)Code);
}
}
/* begin transfer */
lastXchar = XON;
DisplayLine("ASCII: Starting send",NULL,0);
while(SioKeyPress()) SioKeyRead();
/* clear comm port */
SioRxFlush(Port);
/* send ascii file ( stop at ^Z ) */
while(1)
{/* read next buffer from disk */
Count = read(Handle,Buffer,Length);
if(Count==0) break;
if(Count<0)
{SayError(Port,"Error on disk read");
return(FALSE);
}
/* send one byte at a time */
for(i=0;i<Count;i++)
{/* User ABORTS ? */
if(UserAborts(Port)) return(FALSE);
/* send byte */
LastChar = Buffer[i];
if(EchoFlag) MyCrtWrite(LastChar);
/* send the character */
PutChar(Port,LastChar);
if(CharPace>0) SioDelay(CharPace);
/* slight delay after each line */
if(LastChar==LF) SioDelay(4*(CharPace+1));
TxChars++;
/* ^Z marks the end of a text file */
if(LastChar==CTLZ) break;
/* check for incoming XON */
if(lastXchar==XON)
{/* check for incoming XON / XOFF */
Code = GetChar(Port,0);
if(Code>0)
{/* is byte a XOFF ? */
if((char)Code==XOFF)
{/* wait for XON */
DisplayLine("XOFF received",NULL,0);
lastXchar = XOFF;
/* wait for XON */
while(1)
{/* user want to quit ? */
if(SioBrkKey())
{DisplayLine("Canceled by USER",NULL,0);
return(FALSE);
}
Code = GetChar(Port,ONE_SECOND);
if((char)Code==XON)
{DisplayLine("XON received",NULL,0);
lastXchar = XON;
break;
}
} /* end -- while */
} /* end -- if(XOFF) */
} /* end -- if(Code) */
} /* end -- if(XON) */
} /* end -- for(i) */
} /* end -- while */
close(Handle);
/* send termination character */
if(TermChar) PutChar(Port,TermChar);
DisplayLine("ASCII: Transfer Complete",NULL,0);
return(TRUE);
} /* end -- TxAcsii */
int RxAscii(Port,Filename,Buffer,Length,RxQueSize,SyncFlag,TermChar,TimeOut,EchoFlag)
int Port; /* COM port [0..3] */
char Filename[]; /* filename buffer */
char Buffer[]; /* data buffer */
int Length; /* length of data buffer */
int RxQueSize; /* size of PCL receive buffer */
int SyncFlag; /* synchronize with XON 1st */
int TermChar; /* termination character (0x00 ==> none) */
int TimeOut; /* delay (seconds) before assuming that sender is done */
int EchoFlag; /* do local echo if TRUE */
{int i;
int Handle; /* file Handle */
int Code; /* return code */
int lo; /* receive queue low water mark */
int hi; /* receive queue high water mark */
int Index; /* buffer index */
int QueSize; /* current PCL receive queue size */
int RxChars = 0; /* # received chars */
int Count; /* # characters written to disk */
char Temp[81]; /* temporary buffer */
long LastTime; /* time last character was received */
/* begin */
lastXchar = XON;
lo = RxQueSize / 8;
hi = 5 * lo;
DisplayLine("ASCII: Starting receive ",NULL,0);
while(SioKeyPress()) SioKeyRead();
/* clear comm port */
SioRxFlush(Port);
/* open file passed in Filename[] for write */
Handle = open(Filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IWRITE);
if(Handle<0)
{strcpy(Temp,"Cannot open ");
strcat(Temp,Filename);
DisplayLine(Temp,NULL,0);
return(FALSE);
}
/* sync with XON 1st ? */
if(SyncFlag)
{DisplayLine("ASCII: Sending initial XON",NULL,0);
while(1)
{SioPutc(Port,XON);
Code = SioGetc(Port,ONE_SECOND);
if(Code==-1) continue;
/* transmitter is sending ! */
SioUnGetc(Port,Code);
break;
}
}
/* receive text */
LastTime = SioTimer();
Index = 0;
while(1)
{/* user want to quit ? */
if(SioBrkKey())
{DisplayLine("Canceled by USER",NULL,0);
return(FALSE);
}
/* check on PCL receive queue size */
QueSize = SioRxQue(Port);
if((QueSize>hi)&&(lastXchar==XON))
{PutChar(Port,XOFF);
lastXchar = XOFF;
DisplayLine("sending XOFF(1)",NULL,0);
/*printf("\nQueSize=%d lo=%d hi=%d\n",QueSize,lo,hi);*/
}
if((QueSize<lo)&&(lastXchar==XOFF))
{PutChar(Port,XON);
lastXchar = XON;
DisplayLine("sending XON ",NULL,0);
}
/* User ABORTS ? */
if(UserAborts(Port)) return(FALSE);
/* get next byte */
Code = GetChar(Port,ONE_SECOND);
if(Code==-1)
{/* done if having exceeded timeout */
if(SioTimer()-LastTime>ONE_SECOND*TimeOut)
{/* sender must be done */
Buffer[Index] = CTLZ;
break;
}
continue;
}
/* ignore 1st character if it is a 0 */
if((RxChars==0)&&((char)Code=='\0')) continue;
LastTime = SioTimer();
/* ignore XON & XOFF ( since we are the receiver ) */
if((char)Code==XON) continue;
if((char)Code==XOFF) continue;
/* received a character */
Buffer[Index++] = (char)Code;
RxChars++;
/* TermChar marks the end of a text file */
if((char)Code==TermChar)
{/* replace TermChar with ^Z */
Buffer[Index-1] = CTLZ;
RxChars++;
break;
}
if(EchoFlag) MyCrtWrite((char)Code);
if(Index==Length)
{/* send XOFF to transmitter */
PutChar(Port,XOFF);
lastXchar = XOFF;
DisplayLine("sending XOFF(2)",NULL,0);
/* write disk file */
Count = write(Handle,Buffer,Index);
if(Count<0)
{SayError("Disk read error",NULL);
SioDelay(ONE_SECOND);
return(FALSE);
}
/* send XON to sender */
PutChar(Port,XON);
lastXchar = XON;
DisplayLine("sending XON ",NULL,0);
Index = 0;
} /* end -- if */
} /* end -- while */
/* write any remaining data in buffer */
if(Index>0)
{Count = write(Handle,Buffer,Index);
if(Count<0)
{SayError("Disk read error",NULL);
SioDelay(ONE_SECOND);
return(FALSE);
}
} /* end -- if */
close(Handle);
DisplayLine("ASCII: Transfer Complete",NULL,0);
return(TRUE);
} /* RxAscii */
int UserAborts(Port)
int Port;
{char UserChar;
/* user aborts ? */
if(SioKeyPress())
{UserChar = (char)SioKeyRead();
if(UserChar==CAN)
{TxCAN(Port);
SioPutc(Port,ETX);
DisplayLine("*** Canceled by USER ***",NULL,0);
return(TRUE);
}
/* send user char */
SioPutc(Port,UserChar);
}
return(FALSE);
} /* UserAborts */